import 'dart:convert';
import 'dart:io';

class IntlArbFile {
  IntlArbFile({required String path, required this.locale}) : file = File(path) {
    readStrings();
  }

  final File file;
  final String locale;
  late final Map<String, String> strings = {};

  int translated(Set<String> keys) {
    int count = 0;
    for (final key in keys) {
      final value = strings[key];
      if (value != null && value.isNotEmpty) {
        count++;
      }
    }
    return count;
  }

  void saveAll(Map<String, String> strings) {
    readStrings();
    this.strings.addAll(strings);
    writeStrings();
  }

  void delete({required String key}) {
    readStrings();
    strings.remove(key);
    writeStrings();
  }

  Map<String, dynamic> difference(IntlArbFile arbFile) {
    return differenceWithStrings(arbFile.strings);
  }

  Map<String, dynamic> differenceWithStrings(Map<String, String> otherStrings, {Set<String> skip = const {}}) {
    final newStrings = <String, String>{};
    final modifiedStrings = <String, dynamic>{};

    for (var element in strings.entries) {
      final key = element.key;
      final value = element.value;
      if (skip.contains(key)) {
        continue;
      }

      final otherValue = otherStrings[key];
      if (otherValue == null) {
        newStrings[key] = value;
      } else if (otherValue != value) {
        modifiedStrings[key] = {
          'old': otherValue,
          'new': value,
        };
      }
    }

    final results = <String, dynamic>{};
    if (newStrings.isNotEmpty) {
      results['new'] = newStrings;
    }
    if (modifiedStrings.isNotEmpty) {
      results['modified'] = modifiedStrings;
    }

    return results;
  }

  void readStrings() {
    if (file.existsSync()) {
      final String content = file.readAsStringSync();
      final json = jsonDecode(content) as Map<String, dynamic>;
      for (var element in json.entries) {
        strings[element.key] = element.value as String;
      }
    } else {
      strings.clear();
    }
  }

  void writeStrings() {
    file.writeAsStringSync(JsonEncoder.withIndent('  ').convert(strings));
  }

  Set<String> get availableKeys {
    final keys = <String>{};
    for (var element in strings.entries) {
      final key = element.key;
      final value = element.value;
      if (value.isNotEmpty) {
        keys.add(key);
      }
    }
    return keys;
  }
}
